package View;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import DAO.AlunoDaoImplArquivo;
import DAO.AtividadeDaoImplArquivo;
import DAO.DisciplinaDaoImplArquivo;
import DAO.HistoricoDaoImplArquivo;
import DAO.HistoricoTurmaDaoImplArquivo;
import DAO.NotaDaoImplArquivo;
import DAO.ProfessorDaoImplArquivo;
import DAO.TurmaDaoImplArquivo;
import Pojo.Aluno;
import Pojo.Atividade;
import Pojo.Disciplina;
import Pojo.Historico;
import Pojo.HistoricoTurma;
import Pojo.Nota;
import Pojo.Professor;
import Pojo.Turma;
import View.MenuDisciplina.Comparador;

/** Classe de operações referentes às disciplinas.
*
* @author Maione José
* 
* */
public class MenuTurma {

	/**
	 * Classe comparador para ordenar as Turma
	 * @author Maione José
	 *
	 */
	public class Comparador implements Comparator<Turma>{
		
		/**
		 * Método de comparação que implementa o método de Comparator
		 */
		public int compare(Turma turma1, Turma turma2){
			if (turma1.getAno() < turma2.getAno()){
				return(-1);
			}else if (turma1.getAno()>turma2.getAno()){
				return(1);
			}
			return(0);
		}
	}
	
	/**Método para cadastro de Turmas no Sistema
	 * 
	 * @param turmaDao
	 * @param professorDao
	 * @param disciplinaDao
	 * @param alunoDao
	 * @param historicoTurmaDao
	 */
	public void cadastrarTurmas(TurmaDaoImplArquivo turmaDao, ProfessorDaoImplArquivo professorDao,DisciplinaDaoImplArquivo disciplinaDao, AlunoDaoImplArquivo alunoDao, HistoricoTurmaDaoImplArquivo historicoTurmaDao){
		System.out.println("-----Cadastrando Nova Turma-----");
		int continuar=1;
		int idDisciplina;
		int idProfessor;
		MenuDisciplina menuDisciplina = new MenuDisciplina();
		MenuProfessor menuProfessor = new MenuProfessor();
		MenuHistoricoTurma menuHistoricoTurma = new MenuHistoricoTurma();
		
		while(continuar==1){		
			int idTurma = turmaDao.getProximoId();
			
			//Requisitando a Disciplina 
			if (menuDisciplina.escolherDisciplinas(disciplinaDao)==0){
				System.out.println("Nenhuma Disciplina Cadastrada. Cadastre uma disciplina para cadastrar uma turma.\nPressione Enter para continuar.");
				Console.readString();
				break;
			}
			idDisciplina = Console.readInteger();
			Disciplina disciplina = disciplinaDao.procurarPorId(idDisciplina);
			while (disciplina == null){
				System.out.println("Entrada inválida. Informe novamente:");
				idDisciplina = Console.readInteger();
				disciplina = disciplinaDao.procurarPorId(idDisciplina);
			}
			
			//Requisitando o Professor
			if (menuProfessor.escolherProfessores(professorDao)==0){
				System.out.println("Nenhum professor cadastrado. Cadastre um professor para cadastrar uma turma.\nPressione Enter para continuar.");
				Console.readString();
				break;
			}
			idProfessor = Console.readInteger();
			Professor professor = professorDao.procurarPorId(idProfessor);
			while (professor == null){
				System.out.println("Entrada inválida. Informe novamente:");
				idProfessor = Console.readInteger();
				professor = professorDao.procurarPorId(idProfessor);
			}
			
			System.out.println("Informe o ano da Turma:");
			int ano = Console.readInteger();
			
			System.out.println("Informe o semestre da Turma:");
			System.out.println("1 - 1º semestre");
			System.out.println("2 - 2º semestre");
			int periodo = Console.readInteger();
			while (periodo!=1&&periodo!=2){
				System.out.println("Entrada inválida. Informe novamente:");
				periodo = Console.readInteger();
			}
			
			System.out.println("Informe o local da Turma:");
			String local = Console.readString();
			
			System.out.println("Informe o horário da Turma: Exemplo: 08:00-09:40");
			String horario = Console.readString();
			
			System.out.println("Informe o numero de vagas da Turma:");
			int numeroDeVagas = Console.readInteger();
			
			List<Atividade> listaAtividades = new ArrayList<Atividade>();
			List<HistoricoTurma> listaHistoricoTurma = new ArrayList<HistoricoTurma>();
			
			Turma novaTurma = new Turma(idTurma,ano,periodo,local,horario,numeroDeVagas,false,professor,disciplina,listaAtividades,listaHistoricoTurma);
			turmaDao.adicionarTurma(novaTurma);
			
			menuHistoricoTurma.cadastrarHistoricoTurma(novaTurma,turmaDao,alunoDao,historicoTurmaDao);
			
			System.out.println("Deseja cadastrar mais uma turma? (1-Sim, 0-Não)");
			continuar = Console.readInteger();
		}
	}
	
	/**Método para escolha de turmas dentre as listadas
	 * 
	 * @param turmaDao
	 * @param professorAcesso
	 */
	public void escolherTurmas(TurmaDaoImplArquivo turmaDao, Professor professorAcesso){
		System.out.println("---Escolha a Turma---");
		
		List<Turma> listaTurmas = turmaDao.getListaTurma();
		Iterator<Turma> i = listaTurmas.iterator();
		Turma turma;
		while(i.hasNext()){
			turma = (Turma) i.next();
			if (turma.getProfessor().getIdProfessor() == professorAcesso.getIdProfessor()){
				System.out.println(turma.getIdTurma() + " - "+turma.getDisciplina().getNome()+" - "+ turma.getAno()+ " " + turma.getPeriodo() + " " + turma.getLocal());
			}
		}
	}
	
	/**Método para escolha de turmas que ainda estão em aberto.
	 * 
	 * @param turmaDao
	 * @param professorAcesso
	 */
	public int escolherTurmasAbertas(TurmaDaoImplArquivo turmaDao, Professor professorAcesso){
		System.out.println("---Escolha a Turma---");
		List<Turma> listaTurmas = turmaDao.getListaTurma();
		Iterator<Turma> i = listaTurmas.iterator();
		Turma turma;
		int contador=0;
		
		if (!(listaTurmas.isEmpty())){
			while(i.hasNext()){
				turma = (Turma) i.next();
				if ((turma.getProfessor().getIdProfessor() == professorAcesso.getIdProfessor())&&(turma.getFinalizada()==false)){
					System.out.println(turma.getIdTurma() + " - "+turma.getDisciplina().getNome()+" - "+ turma.getAno()+ " " + turma.getPeriodo() + " " + turma.getLocal());
					contador++;
				}
			}
		}
		return(contador);
	}
	
	/**Listagem de Turmas cadastradas no sistema.
	 * 
	 * @param turmaDao
	 */
	public void listarTurmas(TurmaDaoImplArquivo turmaDao){
		System.out.println("---Lista de Turmas---");
		
		List<Turma> listaTurmas = turmaDao.getListaTurma();
		Comparador comparador = new Comparador();
		Collections.sort(listaTurmas,comparador);
		
		Iterator<Turma> i = listaTurmas.iterator();
		Turma turma;
		System.out.println("Ano | Período | Horário | Local | Número de Vagas | Professor | Disciplina ");
		while(i.hasNext()){
			turma = (Turma) i.next();
			System.out.println(turma.getAno() + " | " + turma.getPeriodo() + " | " + turma.getHorario() + " | " + turma.getLocal() + " | " + turma.getNumeroDeVagas() + " | " + turma.getProfessor().getNome() + " | " + turma.getDisciplina().getNome());
		}
		System.out.println("Pressione enter para retornar.");
		Console.readString();
	}

	/**Método para fechamento de determinada turma.
	 * 
	 * @param professorAcesso
	 * @param turmaDao
	 * @param atividadeDao
	 * @param disciplinaDao
	 * @param alunoDao
	 * @param historicoTurmaDao
	 * @param notaDao
	 * @param historicoDao
	 */
	public void fecharTurmas(Professor professorAcesso, TurmaDaoImplArquivo turmaDao, AtividadeDaoImplArquivo atividadeDao, DisciplinaDaoImplArquivo disciplinaDao, AlunoDaoImplArquivo alunoDao, HistoricoTurmaDaoImplArquivo historicoTurmaDao, NotaDaoImplArquivo notaDao, HistoricoDaoImplArquivo historicoDao){
		if (this.escolherTurmasAbertas(turmaDao,professorAcesso)==0){
			System.out.println("Todas as turmas fechadas para este professor.");
			Console.readString();
			return;
		}
		int idTurma = Console.readInteger();
		Turma turma = turmaDao.pesquisarPorId(idTurma);
		while ((turma==null)||(turma.getProfessor().getIdProfessor()!=professorAcesso.getIdProfessor())){
			System.out.println("Entrada inválida. Turma não pertence ao professor. Informe novamente:");
			idTurma = Console.readInteger();
			turma = turmaDao.pesquisarPorId(idTurma);
		}
		
		//Buscando dados relacionados com a Turma
		Disciplina disciplina = turma.getDisciplina();
		List<Atividade> listaAtividades = atividadeDao.procurarPorTurma(idTurma);
		List<Aluno> listaAlunos = historicoTurmaDao.pesquisarAlunosPorTurma(turma);
		
		//Somando as notas dos alunos para cada atividade
		Iterator<Aluno> ialuno = listaAlunos.iterator();
		Aluno alunoComparacao;
		Atividade atividadeComparacao;
		Nota notaComparacao;
		MenuNota menuNota = new MenuNota();
		MenuHistoricoTurma menuHistoricoTurma = new MenuHistoricoTurma();
		HistoricoTurma historicoTurma;
		Historico historico;
		double notaAluno;
		double totalAtividades;
		int idNota;
		while(ialuno.hasNext()){
			alunoComparacao = (Aluno) ialuno.next();
			notaAluno = 0.0;
			totalAtividades = 0.0;
			Iterator<Atividade> iatividade = listaAtividades.iterator();
			while(iatividade.hasNext()){
				atividadeComparacao = (Atividade) iatividade.next();
				totalAtividades += atividadeComparacao.getValor();
				idNota = (notaDao.verificarLancamento(alunoComparacao.getIdAluno(), atividadeComparacao.getIdAtividade()));
				while (idNota ==-1){
					System.out.println("Não existe nota lançada para o aluno "+alunoComparacao.getNome()+" e para a atividade "+atividadeComparacao.getNome());
					menuNota.lancarNota(notaDao, alunoComparacao, atividadeComparacao, 0, idNota);
					idNota = notaDao.verificarLancamento(alunoComparacao.getIdAluno(), atividadeComparacao.getIdAtividade());
				}
				notaComparacao = notaDao.procurarPorId(idNota);
				notaAluno += notaComparacao.getNota();				
			}
			historicoTurma = historicoTurmaDao.procurarPorAlunoETurma(alunoComparacao, turma);
			historicoTurma = menuHistoricoTurma.lancarDadosHistoricoTurma(historicoTurma, historicoTurmaDao,notaAluno,disciplina.getCargaHoraria(), totalAtividades);
			if (historicoTurma.isAprovado()==true){
				historico = new Historico(historicoDao.getProximoId(),historicoTurma.getNota(),historicoTurma.getNumeroDeFaltas(),alunoComparacao,disciplina);
				historicoDao.adicionarHistorico(historico);
			}
		}
		turma.setFinalizada(true);
		turmaDao.removerTurma(turma);
		turmaDao.adicionarTurma(turma);
	}
	
	/**Método para consulta da situação de determinada turma.
	 * 
	 * @param turmaDao
	 * @param disciplinaDao
	 * @param historicoTurmaDao
	 */
	public void consultarTurmas(TurmaDaoImplArquivo turmaDao, DisciplinaDaoImplArquivo disciplinaDao, HistoricoTurmaDaoImplArquivo historicoTurmaDao){
		System.out.println("----- Consultando Turma -----");
		int idDisciplina;
		int ano;
		int periodo;
		MenuDisciplina menuDisciplina = new MenuDisciplina();
				
		//Requisitando a Disciplina 
		menuDisciplina.escolherDisciplinas(disciplinaDao);
		idDisciplina = Console.readInteger();
		Disciplina disciplina = disciplinaDao.procurarPorId(idDisciplina);
		while (disciplina == null){
			System.out.println("Entrada inválida. Informe novamente:");
			idDisciplina = Console.readInteger();
			disciplina = disciplinaDao.procurarPorId(idDisciplina);
		}
		
		System.out.println("Informe o ano da turma:");
		ano = Console.readInteger();
		
		System.out.println("Informe o período da turma:");
		periodo = Console.readInteger();
		
		List<Turma> listaTurmas = turmaDao.pesquisarPorDisciplinaAnoPeriodo(idDisciplina, ano, periodo);
		if (listaTurmas.size()==0){
			System.out.println("Nenhuma turma encontrada na pesquisa.");
		}else{
			Iterator<Turma> i = listaTurmas.iterator();
			Turma turma;
			HistoricoTurma historicoTurma;
			List <HistoricoTurma> listaHistoricoTurmas;
			while(i.hasNext()){
				turma = (Turma) i.next();
				listaHistoricoTurmas = historicoTurmaDao.procurarPorTurma(turma);
				Iterator<HistoricoTurma> j = listaHistoricoTurmas.iterator();
				System.out.println("Dados da Turma: \n");
				System.out.println("Disciplina: "+turma.getDisciplina().getNome());
				System.out.println("Professor: "+turma.getProfessor().getNome());
				System.out.println(turma.getDisciplina().getNome()+" | "+turma.getAno()+" | "+turma.getPeriodo()+" | "+turma.getLocal()+" | "+turma.getHorario()+"\n");
				System.out.println("Nome do aluno | Nota | Faltas | Aprovação");
				while (j.hasNext()){
					historicoTurma = (HistoricoTurma) j.next();
					System.out.println(historicoTurma.getAluno().getNome()+" | "+historicoTurma.getNota()+" | "+historicoTurma.getNumeroDeFaltas()+" | "+historicoTurma.isAprovado());
				}
			}
		}
		
		System.out.println("\nPressione Enter para voltar ao menu.");
		Console.readString();
	}
}
